package cn.tedu.rpc;

import com.rabbitmq.client.*;
import com.rabbitmq.client.AMQP.BasicProperties;

import java.io.IOException;
import java.util.Scanner;
import java.util.UUID;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class Client {
    static BlockingQueue<Long> bq = new ArrayBlockingQueue<Long>(10);

    public static void main(String[] args) throws Exception{
        System.out.print("求第几个斐波那契数:");
        int n = new Scanner(System.in).nextInt();
        Long fbnqs = fbnqs(n);
        System.out.println("第"+n+"个斐波那契数是:"+fbnqs);
    }
    //异步调用服务器，从服务器中获取计算结果
    public static Long fbnqs(int n) throws Exception{
        //1.配置RabbitMQ的连接信息
        ConnectionFactory cf = new ConnectionFactory();
        cf.setHost("127.0.0.1");
        cf.setUsername("guest");
        cf.setPassword("guest");
        //2.创建tcp和channel
        Connection nc = cf.newConnection();
        Channel cc = nc.createChannel();
        //3.创建调用队列
        cc.queueDeclare("rpc_queue",false,false,false,null);
        cc.queuePurge("rpc_queue");
        //4.定义返回队列的队列名
        String replyTo = cc.queueDeclare().getQueue();
        //5.关联id
        String cid = UUID.randomUUID().toString();
        //replyTo和cid通过BasicProperties发送到调用队列中
        BasicProperties basicProperties = new BasicProperties().builder()
                .replyTo(replyTo)
                .correlationId(cid)
                .build();
        cc.basicPublish("","rpc_queue",basicProperties,(n+"").getBytes());
        System.out.println("模拟其他运算，不等待结果");
        //从返回队列中取结果
        DeliverCallback deliverCallback = new DeliverCallback() {
            @Override
            public void handle(String s, Delivery delivery) throws IOException {
                //取出数据之前先对比cid
                if(cid.equals(delivery.getProperties().getCorrelationId())){
                    int fbnqs = Integer.parseInt(new String(delivery.getBody()));
                    bq.offer((long) fbnqs);
                    cc.getConnection().close();
                }
            }
        };
        CancelCallback cancelCallback = new CancelCallback() {
            @Override
            public void handle(String s) throws IOException {

            }
        };
        cc.basicConsume(replyTo,true,deliverCallback,cancelCallback);
        return bq.take();
    }
}
